<?php
// 接口-生产加工单接口
namespace interface\v1;

use verify;

class machiningOrderClass extends index
{
	
	private const page           = 'machiningOrder';
	private const table          = 'machining_order';
	private const tableMx        = 'machining_order_detail';
	private const table_material = 'machining_order_mx';
	private const title          = '生产加工单';
	
	public function search()
	{
		$this->code         = 1;
		$this->resp['data'] = [
			'orderBy' => [
				'创建时间降序',
				'创建时间升序',
				'计划开始时间降序',
				'计划开始时间升序',
				'计划完工时间降序',
				'计划完工时间升序',
			],
			'search'  => [
				[
					'key'   => 'type',
					'name'  => '加工单类型',
					'array' => ['生产加工', '生产返工'],
				],
				[
					'key'   => 'line',
					'name'  => '生产线',
					'array' => find([
						'table' => 'product_line',
						'field' => "id as value, name as text ",
						'where' => "coid = '" . self::$coid . "'",
					])['array'],
				],
				[
					'key'   => 'recordDate',
					'name'  => '计划开始时间',
					'array' => [
						'今天', '近7天', '近30天', '自定义',
					],
				],
				[
					'key'   => 'state',
					'name'  => '状态',
					'array' => [
						'草稿', '待确认', '已确认',
					],
				],
			],
		];
	}
	
	/**
	 * 列表
	 *
	 * @return void
	 */
	public function list(): void
	{
		$where = '';
		//获取查询结果
		$where .= search([
			"="    => [
				'a.coid'  => self::$coid,
				'a.state' => $this->post('state'),
			],
			'like' => [
				'a.orderNo' => $this->post('orderNo'),
			],
		]);
		if ($this->post('recordDate')) {
			$where .= self::miniTimeComparison($this->post('recordDate'), 'date', 'a.recordDate');
		}
		// $page = $this->page(["table" => self::table, "where" => $where, "order" => "time desc"]);
		$page = $this->page([
			"table" => self::table . " as a join " . self::table_material . ' as c on c.orderId = a.id join material as b on c.materialId = b.id ',
			'field' => "c.*,b.name as materialName,b.code,b.model,a.state,a.lineId,a.orderNo,a.type,a.startDate,a.endDate,a.recordDate, a.stid",
			"where" => $where,
			"order" => "a.recordDate desc, a.time desc",
		]);
		//数据分析
		$data['result'] = [];
		foreach ($page['array'] as $array) {
			$line             = query('product_line', "id = '$array[lineId]'");
			$material         = query('material', " id = '$array[materialId]' ");
			$materialSku      = query('material_sku', " id = '$array[materialSkuId]' ");
			$data['result'][] = [
				"id"        => $array['orderId'],
				'orderNo'   => $array['orderNo'],
				'startDate' => self::formatDate($array['startDate'], 'm月d日'),
				'endDate'   => self::formatDate($array['endDate'], 'm月d日'),
				'line'      => $line['workshop'] . '-' . $line['name'],
				'code'      => $material['code'],
				'name'      => $material['name'],
				'skuName'   => $materialSku['name'],
				"state"     => $array['state'],
				'staffName' => self::findStaff($array['stid']),
				'num'       => $array['num'],
				'unit'      => $array['unit'],
				'time'      => self::formatDate($array['time'], 'Y/m/d'),
			];
		}
		$data['page'] = $page['para'];
		//返回
		$this->code         = 1;
		$this->resp['data'] = $data;
	}
	
	
	/**
	 * 详情
	 *
	 * @return void
	 */
	public function detail(): void
	{
		$id   = $this->post('id');
		$info = query(self::table, "id = '" . $id . "'");
		// if (!in_array(self::$stid, [$info['checkId'], $info['manager'], $info['stid']])) {
		// 	$this->resp['warn'] = '这不是您的' . self::title;
		// } else
		if (empty($id)) {
			$this->resp['warn'] = "ID为空";
		} elseif (empty($info['id'])) {
			$this->resp['warn'] = "未找到此" . self::title;
		} else {
			$audit       = find([
				'table' => 'auditing_follow',
				'where' => " typeId = '$info[id]' order by time desc",
			]);
			$line        = query('product_line', "id = '$info[lineId]'");
			$result      = find(['table' => self::table_material, 'where' => "orderId = '$info[id]' order by list"]);
			$materialArr = [];
			foreach ($result['array'] as $array) {
				$material        = query('material', " id = '$array[materialId]'");
				$materialSku     = query('material_sku', " id = '$array[materialSkuId]'");
				$saleOrderDetail = query('sale_order_detail', "id = '$array[sourceId]'");
				$saleOrder       = query('sale_order', "id = '$saleOrderDetail[orderId]'");
				$bom             = query('bom', "id = '$array[bomId]'");
				$routing         = query('routing', "id = '$array[routingId]'");
				$materialArr[]   = [
					'id'              => $array['id'],
					'material'        => $material['code'] . '-' . $material['name'] . '-' . $material['model'] . '-' . $materialSku['name'],
					'materialId'      => $array['materialId'],
					'materialSkuId'   => $materialSku['id'],
					'materialCode'    => $material['code'],
					'materialName'    => $material['name'],
					'materialSkuName' => $materialSku['name'],
					'brand'           => $material['brand'],
					'model'           => $material['model'],
					'num'             => $array['num'],
					'unit'            => $array['unit'],
					'saleOrderId'     => $array['sourceId'],
					'saleOrderNo'     => $saleOrder['orderNo'],
					'sourceId'        => $array['sourceId'],
					'bomId'           => $array['bomId'],
					'bomVersion'      => $bom['bomVersion'],
					'description'     => $routing['description'],
					'routingName'     => $routing['description'],
					'routingId'       => $routing['id'],
					'text'            => $array['text'],
					'saleOrderDetail' => $saleOrderDetail,
				];
			}
			$data['result'] = [
				'info'        => [
					"id"         => $info['id'],
					'staffName'  => self::findStaff($info['stid']),
					'stid'       => $info['stid'],
					'type'       => $info['type'],
					'startDate'  => $info['startDate'],
					'endDate'    => $info['endDate'],
					'orderNo'    => $info['orderNo'],
					'recordDate' => self::formatDate($info['time']),
					'workshop'   => $line['workshop'],
					'lineName'   => $line['name'],
					'lineId'     => $info['lineId'],
					"state"      => $info['state'],
					'text'       => $info['text'],
					'date'       => self::formatDate($info['time'], 'm/d'),
				],
				'material'    => $materialArr,
				'auditRecord' => $audit['array'],
			];
			//返回
			$this->code         = 1;
			$this->resp['data'] = $data;
		}
	}
	
	/**
	 * 获取订单
	 *
	 * @return void
	 */
	public function getOrder(): void
	{
		$result = find([
			'table' => 'sale_order as o, kehu as k',
			'field' => 'o.*, k.companyName',
			'where' => generateWhere([
					'o.state'   => '已确认',
					'o.isClose' => 0,
					'o.coid'    => self::$coid,
				]) . " AND o.khid = k.khid ",
		]);
		$array  = [];
		foreach ($result['array'] as $item) {
			// $manager = self::findStaff($item['manager']);
			$array[] = [
				'value' => $item['id'],
				'text'  => $item['companyName'] . '/' . $item['orderNo'],
				// 'text'  => $item['companyName'] . '/' . $item['orderNo'] . '/￥' . $item['money'] . '/' . $manager,
			];
		}
		$this->resp['data'] = $array;
		$this->code         = 1;
	}
	
	public function getMaterial()
	{
		$where = ['coid' => self::$coid,];
		if ($this->post('orderId')) {
			$where['orderId'] = $this->post('orderId');
		}
		$result = find([
			'table' => 'sale_order_detail',
			'field' => ' `id`,`materialId`, `materialSkuId`, `num`, `price`, `money`, `rate`, `text`',
			'where' => generateWhere($where),
		]);
		$array  = [];
		foreach ($result['array'] as $item) {
			$material                      = query('material', " id = '$item[materialId]' ");
			$materialSku                   = query('material_sku', " id = '$item[materialSkuId]' ");
			$bom                           = find([
				'field' => "id as value, bomVersion as text",
				'table' => 'bom',
				'where' => "materialId = '$item[materialId]' and state = '启用' ",
			]);
			$routing                       = find([
				'field' => "id as value, description as text",
				'table' => 'routing',
				'where' => "coid = '" . self::$coid . "' and type = 1 and state = '启用' and materialId = '$material[id]' order by time desc",
			]);
			$temp                          = [
				'id'       => $item['id'],
				'num'      => $item['num'],
				'material' => [
					'text'  => $material['code'] . '-' . $material['name'] . '-' . $material['model'] . '-' . $materialSku['name'],
					'value' => $item['materialSkuId'],
				],
				'unit'     => self::filterArray([$material['unit'], $material['unit_one'], $material['unit_two'],]),
				'bom'      => $bom['array'],
				'routing'  => $routing['array'],
			];
			$array[$item['materialSkuId']] = $temp;
		}
		$this->resp['data'] = $array;
		$this->code         = 1;
	}
	
	public function edit()
	{
		$id               = $this->post('id') ?: self::getId();
		$detail           = !empty($_POST['detail']) ? json_decode($_POST['detail'], true) : [];
		$mxIdArr          = $this->post('mxId') ?: inStockClass::getArrVal('id', $detail);
		$sourceIdArr      = $this->post('sourceId') ?: inStockClass::getArrVal('sourceId', $detail);
		$materialSkuIdArr = $this->post('materialSkuId') ?: inStockClass::getArrVal('materialSkuId', $detail);
		$unitArr          = $this->post('unit') ?: inStockClass::getArrVal('unit', $detail);
		$numArr           = $this->post('num') ?: inStockClass::getArrVal('num', $detail);
		$bomIdArr         = $this->post('bomId') ?: inStockClass::getArrVal('bomId', $detail);
		$routingIdArr     = $this->post('routingId') ?: inStockClass::getArrVal('routingId', $detail);
		
		$field      = [
			'type'      => $this->post('type'),
			'text'      => $this->post('text'),
			'lineId'    => $this->post('lineId'),
			'startDate' => $this->post('startDate'),
			'endDate'   => $this->post('endDate'),
		];
		$annotation = [
			'type'      => '加工单类型',
			'lineId'    => '生产线',
			'startDate' => '计划开工日期',
			'endDate'   => '计划结束日期',
		];
		$rules      = [
			'type'      => 'required',
			'lineId'    => 'required',
			'startDate' => 'required',
			'endDate'   => 'required',
		];
		// 校验是否符合规则
		$vt     = new verify();
		$result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
		if ($result === false) {
			$this->resp['warn'] = $vt->getErrs()[0];  // 多个规则提示最前面一条
			goto resp;
		}
		$where = " id = '$id' ";
		$info  = query(self::table, $where);
		//判断
		if (!$this->power(self::page, "edit")) {
			$this->resp['warn'] = "你没有编辑" . self::title . "的权限";
		} elseif (self::is_null_array($mxIdArr)) {
			$this->resp['warn'] = '请选择需要生产的产品';
		} elseif (self::is_null_array($unitArr)) {
			$this->resp['warn'] = '请填写计划数量';
		} elseif (self::is_null_array($unitArr)) {
			$this->resp['warn'] = '请选择单位';
		} elseif (self::is_null_array($routingIdArr)) {
			$this->resp['warn'] = '请选择工艺路线';
		} elseif (self::is_null_array($bomIdArr)) {
			$this->resp['warn'] = '请选择Bom id';
		} elseif (self::is_null_array($numArr)) {
			$this->resp['warn'] = '请填写额定数量';
		} elseif (self::is_null_array($unitArr)) {
			$this->resp['warn'] = '请选择所需物料的单位';
		} elseif (!empty($info['id']) && $info['state'] == '已确认') {
			$this->resp['warn'] = '此生产加工单已确认，不能修改';
		} else {
			$this->startTrans();
			$isPass = true;//事务通过标志
			if (!$info['id']) {
				$orderNo            = self::generateCode(self::page,[
                    'prefix' => 'SCJG' . date('Ymd'),
                    'table'  => self::table,
                    'field'  => 'orderNo',
                    'where'  => '',
                ],$field);
				$field              = array_merge($field, [
					'id'         => $id,
					'orderNo'    => $orderNo,
					'recordDate' => $this->date,
					'state'      => '草稿',
					'coid'       => self::$coid,
					'stid'       => $this->control['stid'],
					'time'       => $this->time,
				]);
				$this->resp['warn'] = static::insert([
					"table" => self::table,
					"field" => $field,
				]);
			} else {
				$this->resp['warn'] = static::update([
					"table" => self::table,
					"field" => $field,
					"where" => $where,
				]);
			}
			if (!in_array($this->resp['warn'], ["新增成功", "更新成功"])) {
				goto  resp;
			}
			// 子表
			foreach ($materialSkuIdArr as $key => $materialSkuId) {
				$materialId = query('material_sku', "id = '$materialSkuId'", 'materialId')['materialId'];
				$where      = " id = '$mxIdArr[$key]' ";
				$mx         = query(self::table_material, $where);
				$mxFiled    = [
					'id'            => $mxIdArr[$key],
					'orderId'       => $id,
					'coid'          => self::$coid,
					'sourceId'      => $sourceIdArr[$key],
					'sourceTable'   => 'sale_order_detail',
					'materialId'    => $materialId,
					'materialSkuId' => $materialSkuId,
					'num'           => $numArr[$key],
					'unit'          => $unitArr[$key],
					'bomId'         => $bomIdArr[$key],
					'routingId'     => $routingIdArr[$key],
				];
				if (!$mx['id']) {
					$warn = static::insert([
						"table" => self::table_material,
						"field" => $mxFiled,
					]);
				} else {
					$warn = static::update([
						"table" => self::table_material,
						"field" => $mxFiled,
						'where' => $where,
					]);
				}
				if (!in_array($warn, ['新增成功', '更新成功'])) {
					$isPass = false;
					break;
				} else {
					// 通过bom 添加 物料
					$lists = self::bomMx($mxFiled['bomId'], $mxFiled['materialSkuId'], $mxFiled['num'], $mxFiled['unit']);
					if (!is_array($lists) || empty($lists)) {
						$this->resp['warn'] = $lists;
						goto resp;
					}
					// 清空
					delete(['table' => self::tableMx, 'where' => " orderId = '$id'"]);
					//添加或更新明细
					foreach ($lists as $list) {
						$field             = array_merge($list, [
							'id'          => self::getId(),
							'coid'        => self::$coid,
							'orderId'     => $id,
							'targetSkuId' => $mxFiled['materialSkuId'],
						]);
						$field['quantity'] = (1 + $field['loss']) * $field['num'];
						$warn              = static::insert([
							"table" => self::tableMx,
							"field" => $field,
						]);
						if (!in_array($warn, ['新增成功', '更新成功'])) {
							$isPass             = false;
							$this->resp['warn'] = $warn;
							break;
						}
					}
				}
			}
			if (in_array($this->resp['warn'], ["新增成功", "更新成功"]) && $isPass === true) {
				$this->commitTrans();
				//添加日志
				$type = mb_substr($this->resp['warn'], 0, 2, 'utf-8');
				$text = $this->control['name'] . $type . "了" . self::title . " id：【" . $id . '】';
				$this->logText(["type" => self::page, "text" => $text]);
				$this->code         = 1;
				$this->resp['data'] = $id;
			} else {
				$this->rollback();
			}
		}
		
		resp:
	}
	
	
	/**
	 * 计算BOM用料(主单位)
	 */
	public static function bomMx($bomId, $materialSkuId, $num, $unit, &$materialList = [])
	{
		$bom = query('bom', "id = '$bomId' and state = '启用'");
		if (empty($bom['id'])) {
			return '未找到BOM表';
		}
		$materialSku = query('material_sku', "id = '$materialSkuId'");//生产SKU
		$material    = query('material', "id = '$bom[materialId]'");
		//BOM表头物料单位向物料主单位转化
		if ($bom['unit'] == $material['unit_one']) {
			$bom['num'] = $material['unitOne'] * $bom['num'];
		} elseif ($bom['unit'] == $material['unit_two']) {
			$bom['num'] = $material['unitTwo'] * $bom['num'];
		} elseif ($bom['unit'] != $material['unit']) {
			return 'BOM表头物料单位不在物料的单位中';
		}
		//生产单位向主单位转化
		if ($unit == $material['unit']) {
			$pcs = $bom['num'] > 0 ? ($num / $bom['num']) : 0;//需要几个BOM的子物料
		} elseif ($unit == $material['unit_one']) {
			$num = $num * $materialSku['unitOne'];
			$pcs = $bom['num'] > 0 ? ($num / $bom['num']) : 0;//需要几个BOM的子物料
		} elseif ($unit == $material['unit_two']) {
			$num = $num * $materialSku['unitTwo'];
			$pcs = $bom['num'] > 0 ? ($num / $bom['num']) : 0;//需要几个BOM的子物料
		} else {
			return $materialList;
		}
		$bomMx = find(['table' => 'bom_detail', 'where' => "orderId = '$bom[id]' order by list"]);
		foreach ($bomMx['array'] as $array) {
			$materialList[] = ['materialId' => $array['materialId'], 'materialSkuId' => $array['materialSkuId'], 'loss' => $array['loss'], 'num' => $array['num'] * $pcs, 'unit' => $material['unit']];
		}
		return $materialList;
	}
	
	
	/**
	 * 提交
	 */
	public function commit()
	{
		$id    = $this->post('id');
		$info  = query(self::table, " coid = '" . self::$coid . "' AND id = '$id'");
		$field = [
			'state' => '待确认',
		];
		if (!$this->power(self::page, 'edit')) {
			$this->resp['warn'] = '你还没有编辑权限';
		} elseif (empty($info['id'])) {
			$this->resp['warn'] = '未找到此生产加工单';
		} elseif ($info['state'] != '草稿') {
			$this->resp['warn'] = '此生产加工单不是草稿状态，不能提交';
		} else {
			$this->resp['warn'] = update(array(
				"table" => self::table,
				"field" => $field,
				"where" => "id = '$info[id]'",
			));
			if (in_array($this->resp['warn'], ["新增成功", "更新成功"])) {
				auditingFollow([
					"type"   => "生产加工单",
					"typeId" => $info['id'],
					"text"   => "【{$this->control['name']}】提交",
				]);
				//添加日志
				$type = mb_substr($this->resp['warn'], 0, 2, 'utf-8');
				$text = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
				$this->logText(["type" => self::page, "text" => $text]);
				//返回
				$this->code = 1;
			}
		}
		resp:
	}
	
	/**
	 * 确认
	 */
	public function confirmEdit()
	{
		$id    = $this->post('id');
		$info  = query(self::table, " coid = '" . self::$coid . "' AND id = '$id'");
		$field = [
			'state'       => '已确认',
			'checkId'     => self::$stid,
			'confirmTime' => $this->time,
		];
		if (!$this->power(self::page, 'confirm')) {
			$this->resp['warn'] = '你还没有确认权限';
		} elseif (empty($info['id'])) {
			$this->resp['warn'] = '未找到此生产加工单';
		} elseif ($info['state'] != '待确认') {
			$this->resp['warn'] = '此申请不是待确认状态，不能确认';
		} else {
			$this->resp['warn'] = update([
				"table" => self::table,
				"field" => $field,
				"where" => "id = '$info[id]'",
			]);
			if (in_array($this->resp['warn'], ["新增成功", "更新成功"])) {
				auditingFollow(array(
					"type"   => "生产加工单",
					"typeId" => $info['id'],
					"text"   => "【{$this->control['name']}】确认",
				));
				//添加日志
				$type = mb_substr($this->resp['warn'], 0, 2, 'utf-8');
				$text = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
				$this->logText(["type" => self::page, "text" => $text]);
				//返回
				$this->code = 1;
			}
		}
		resp:
	}
	
	/**
	 * 删除
	 *
	 * @return void
	 */
	public function delete(): void
	{
		$array = $this->post('listId') ?? $this->post('id');
		if (!$this->power(self::page, "del")) {
			$this->resp['warn'] = "你没有删除的权限";
		} elseif (empty($array)) {
			$this->resp['warn'] = "你一个数据都没有选择呢";
		} else {
			$text  = "";
			$x     = 0;
			$array = is_array($array) ? $array : [$array];
			foreach ($array as $id) {
				$info = query(self::table, " id = '$id' ");
				if ($info['state'] == '已确认') {
					$warn = "删除失败：已确认，暂不能删除";
				} else {
					//最后删除基本参数
					delete(["table" => self::table, "where" => " id = '$id' "]);
					delete(["table" => self::tableMx, "where" => " orderId = '$id' "]);
					delete(["table" => 'auditing_follow', "where" => " typeId = '$id' "]);
					//返回
					$warn = "删除成功";
					$x++;
				}
				$text .= self::title . "ID【" . $info['id'] . "】" . $warn . "。<br>";
			}
			//添加日志
			$text = $this->control['name'] . "删除了" . self::title . "，结果如下：<br>" . $text;
			$this->logText(array("type" => self::page, "text" => $text));
			$this->resp['warn'] = "删除了" . $x . "个" . self::title . "，详情见系统日志。";
			$this->code         = 1;
		}
	}
}
